package com.hnzq.cloud.driversend.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hnzq.cloud.IO.AddDriverworkIO;
import com.hnzq.cloud.IO.EditSendOrderIO;
import com.hnzq.cloud.IO.entity.FreDriverwork;
import com.hnzq.cloud.IO.entity.FreSend;
import com.hnzq.cloud.OrderAPI;
import com.hnzq.cloud.api.FreDriverworkApi;
import com.hnzq.cloud.api.FreSendOrderApi;
import com.hnzq.cloud.driversend.exception.SendException;
import com.hnzq.cloud.model.Result;
import com.hnzq.cloud.param.JudgeOrderIdsParam;
import com.hnzq.cloud.param.UpdateOrderListStatusParam;
import com.hnzq.cloud.param.UpdateOrderStatusParam;
import com.hnzq.cloud.util.FreException;
import io.seata.core.exception.TransactionException;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RBucket;
import org.redisson.api.RTransaction;
import org.redisson.api.RedissonClient;
import org.redisson.api.TransactionOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("driver")
public class DriverSendController {
    @Autowired
    private FreSendOrderApi freSendOrderApi;
    @Autowired
    private FreDriverworkApi freDriverworkApi;
    @Autowired
    private OrderAPI orderAPI;
    @Autowired
    private RedissonClient redissonClient;
    /**
    * @作者: tiangle
    * @描述：司机调用此接口，进行配送被分配的订单
    * @时间：2022/2/24 17:41
    * @参数类型:[]
    * @返回：com.hnzq.cloud.model.Result
    **/
    @GlobalTransactional
    @PutMapping("beginSend")
    public Result beginSend() throws FreException {
        //当前登陆是否为司机
        ObjectMapper mapper = new ObjectMapper();
        Integer id = mapper.convertValue(((ServletRequestAttributes)
                (RequestContextHolder.currentRequestAttributes())).getRequest()
                .getHeader("userId"), Integer.class);
        RTransaction transaction = redissonClient.createTransaction(TransactionOptions.defaults());
        Result<FreDriverwork> byUserId = freDriverworkApi.getByUserId(id);
        if (byUserId.getCode()!=200||byUserId.getData()==null){
            throw new SendException("无权限",405);
        }
        FreDriverwork data = byUserId.getData();
        //当前司机是否为空闲状态
        if (data.getDriverStatus()!=0) {
            throw new SendException("司机正在配送中",500);
        }
        //开始配送，修改司机状态1、订单状态2、配送单状态1
        Result<FreSend> byDriver = freSendOrderApi.getByDriver(data.getDriverId());
        if (byDriver.getCode()!=200){
            throw new SendException(byDriver.getMessage(),500);
        }
        RBucket<Object> bucket = transaction.getBucket("send:area:" + byDriver.getData().getAreaId());
        if (bucket.isExists()){
            bucket.delete();
        }
        try {
            EditSendOrderIO build = EditSendOrderIO.builder().desc("开始配送").sendId(byDriver.getData().getSendId()).sendStatus(1).build();
            if (freSendOrderApi.editStatus(build).getCode()!=200) {
                throw new SendException("配送单原因配送失败",500);
            }
            Result<List<Integer>> orders = freSendOrderApi.getOrders(byDriver.getData().getSendId());
            UpdateOrderListStatusParam updateOrderListStatusParam  = new UpdateOrderListStatusParam();
            updateOrderListStatusParam.setOrderIds(orders.getData());
            updateOrderListStatusParam.setOrderStatus(2);
        Result<Integer> integerResult = orderAPI.updateOrderListStatus(updateOrderListStatusParam);
        System.out.println(integerResult.getCode()+integerResult.getMessage());
        if (orderAPI.updateOrderListStatus(updateOrderListStatusParam).getCode()!=200) {

                throw new SendException("订单原因配送失败",500);

            }
            AddDriverworkIO build1 = AddDriverworkIO.builder().driverId(data.getDriverId()).driverStatus(1).build();
            if (freDriverworkApi.editDriverworkStatus(build1).getCode()!=200) {
                throw new SendException("司机原因配送失败",500);

            }
            transaction.commit();
        }catch (SendException e){
            transaction.rollback();
            throw new SendException(e.getMessage(),500);
        }catch (Exception e){
            transaction.rollback();
            throw new SendException("系统出现错误，请联系管理员检查系统",500);
        }

        return Result.newInstance().setCode(200).setMessage("开始配送");
    }
    /**
    * @作者: tiangle
    * @描述：每扫描一个order，改变一个order的状态为3，当该配送单最后一个order改变时，整个配送单变为已送达状态
    * @时间：2022/2/22 19:07
    * @参数类型:[]
    * @返回：com.hnzq.cloud.model.Result
    **/
    @GlobalTransactional
    @PutMapping("arriveOrder")
    public Result arriveOrder(@RequestParam("orderId")Integer orderId) throws FreException, JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        Integer id = mapper.convertValue(((ServletRequestAttributes)
                (RequestContextHolder.currentRequestAttributes())).getRequest()
                .getHeader("userId"), Integer.class);
        Result<FreDriverwork> byUserId = freDriverworkApi.getByUserId(id);
        if (byUserId.getCode()!=200||byUserId.getData()==null){
            throw new SendException("无权限",405);
        }
        JudgeOrderIdsParam judgeOrderIdsParam = new JudgeOrderIdsParam();
        judgeOrderIdsParam.setOrderStatus(2);
        ArrayList<Integer> objects = new ArrayList<>();
        objects.add(orderId);
        judgeOrderIdsParam.setOrderIds(objects);
        Result<Boolean> booleanResult = orderAPI.judgeOrderIds(judgeOrderIdsParam);
        System.out.println(booleanResult.getMessage());
        if (!booleanResult.getData()) {
            throw new SendException("该订单状态有异常",500);
        }
        UpdateOrderStatusParam statusParam = new UpdateOrderStatusParam();
        statusParam.setOrderId(orderId);
        statusParam.setOrderStatus(3);
        if (orderAPI.updateOrderStatus(statusParam).getCode()!=200) {
            throw new SendException("订单状态修改失败",500);
        }
        Result<FreSend> sendByOrder = freSendOrderApi.getSendByOrder(orderId);
        Result<List<Integer>> orders = freSendOrderApi.getOrders(sendByOrder.getData().getSendId());
        judgeOrderIdsParam.setOrderIds(orders.getData());
        judgeOrderIdsParam.setOrderStatus(3);
        //判断所有order都为配送完成状态
        if (orderAPI.judgeOrderIds(judgeOrderIdsParam).getData()) {
            EditSendOrderIO build = EditSendOrderIO.builder().desc("配送完成").sendId(sendByOrder.getData().getSendId()).sendStatus(2).build();
            if (freSendOrderApi.editStatus(build).getCode()!=200) {
                throw new SendException("配送单状态修改失败",500);
            }
            AddDriverworkIO addDriverworkIO = new AddDriverworkIO();
            addDriverworkIO.setDriverId(sendByOrder.getData().getDriverId());
            addDriverworkIO.setDriverStatus(2);
            if (freDriverworkApi.editDriverworkStatus(addDriverworkIO).getCode()!=200) {
                throw new SendException("司机状态修改失败",500);
            }
        }
        return Result.newInstance().setCode(200).setMessage("订单已送达");
    }

    @GlobalTransactional
    @PutMapping("arriveHouse")
    public Result arriveHouse(@RequestParam("driverId")Integer driverId) throws FreException, JsonProcessingException {
        AddDriverworkIO addDriverworkIO = new AddDriverworkIO();
        addDriverworkIO.setDriverId(driverId);
        addDriverworkIO.setDriverStatus(3);
        if (freDriverworkApi.editDriverworkStatus(addDriverworkIO).getCode()!=200) {
            throw new SendException("司机状态修改失败",500);
        }
        return Result.newInstance().setCode(200).setMessage("设置成功");
    }
    @GlobalTransactional
    @PutMapping("arrivedHouse")
    public Result arrivedHouse(@RequestParam("driverId")Integer driverId) throws FreException, JsonProcessingException {
        AddDriverworkIO addDriverworkIO = new AddDriverworkIO();
        addDriverworkIO.setDriverId(driverId);
        addDriverworkIO.setDriverStatus(0);
        if (freDriverworkApi.editDriverworkStatus(addDriverworkIO).getCode()!=200) {
            throw new SendException("司机状态修改失败",500);
        }
        return Result.newInstance().setCode(200).setMessage("设置成功");
    }

}
